<?php

declare(strict_types=1);

namespace owns\middleware;

use owns\enum\CacheMap;
use owns\enum\AppEnum;
use owns\enum\RespCode;
use owns\facade\JwtAuth;
use owns\facade\OperLog;
use owns\interface\MiddlewareInterface;
use think\facade\Cache;
use think\facade\Config;
use think\Response;

/**
 * 服务端权限中间件
 */
class ServerAuthMiddleware extends MiddlewareInterface
{
    /**
     * 处理请求信息
     * @param Request $request
     * @param string $token
     * @param Closure  $next
     * @return Response
     */
    public function handleRequest($request, $token, $next)
    {
        $request->port = AppEnum::PORT_USER;
        if (!$token) {
            tips('请先登录', RespCode::NOT_LOGIN);
        }
        if($request->uid == 0) {
            self::authority($request, $token);
        }
        // 权限验证
        $oper = OperLog::permissionVerify($request);
        $response = $next($request);
        // 写入日志
        if ($oper) {
            $oper->write($response);
        }
        return $response;
    }
    /**
     * 授权验证
     * @param Request $request
     * @param string $token
     */
    public static function authority(&$request, $token): void
    {
        $user = JwtAuth::verify($token);
        if (!$user) {
            tips('请重新登录', RespCode::NOT_LOGIN);
        }
        $cacheToken = Cache::store('redis')->hget(CacheMap::OWN_USIGN, CacheMap::userCache($user->uid));
        if (!$cacheToken) {
            tips('请重新登录', RespCode::NOT_LOGIN);
        }
        if (Config::get('jwt.user_login') == 'sso' && $cacheToken != $token) {
            tips('你已被登出，请重新登录', RespCode::NOT_LOGIN);
        }
        $request->uid = (int) $user->uid;
        $request->auth = $user;
    }
}
